home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-05-01 | 17.2 KB | 549 lines | [TEXT/MPS ] |
- // UDependencies.cp
- // Copyright © 1988-1991 by Apple Computer Inc. All rights reserved.
-
- #ifndef __UDEPENDENCIES__
- #include "UDependencies.h"
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
- #ifndef __UITERATOR__
- #include <UIterator.h>
- #endif
-
-
- //--------------------------------------------------------------------------------------------------
-
- TDependenciesByNotifier* gDependenciesByNotifier = NULL;
- TDependenciesByDependent* gDependenciesByDependent = NULL;
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal TDependenciesByNotifier* NewDependenciesByNotifier(void)
- {
- TDependenciesByNotifier * dependencies = new TDependenciesByNotifier;
-
- dependencies->IDependencies();
- return dependencies;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal TDependenciesByDependent* NewDependenciesByDependent(void)
- {
- TDependenciesByDependent * dependencies = new TDependenciesByDependent;
-
- dependencies->IDependencies();
- return dependencies;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void AddDependentOf(TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel)
- {
- if (gDependenciesByNotifier == NULL)
- gDependenciesByNotifier = NewDependenciesByNotifier();
- if (gDependenciesByDependent == NULL)
- gDependenciesByDependent = NewDependenciesByDependent();
- gDependenciesByNotifier->AddDependency(notifier, dependent, dependencyLabel);
- gDependenciesByDependent->AddDependency(notifier, dependent, dependencyLabel);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void RemoveDependentOf(TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel)
- {
- if (gDependenciesByNotifier)
- gDependenciesByNotifier->RemoveDependency(notifier, dependent, dependencyLabel);
- if (gDependenciesByDependent)
- gDependenciesByDependent->RemoveDependency(notifier, dependent, dependencyLabel);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- //RCR Former nested routines
- pascal void DeleteByDependent(ArrayIndex index,
- TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel,
- void* /* staticLink */)
-
- {
- gDependenciesByDependent->DeleteElementsAt(index, 1);
- gDependenciesByNotifier->RemoveDependency(notifier, dependent, dependencyLabel);
- }
-
-
- pascal void DeleteByNotifier(ArrayIndex index,
- TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel,
- void* /* staticLink */)
-
- {
- gDependenciesByNotifier->DeleteElementsAt(index, 1);
- gDependenciesByDependent->RemoveDependency(notifier, dependent, dependencyLabel);
- }
-
-
- pascal void RemoveDependencies(TObject* anObject)
- {
- long NullStaticLink; // Use &NullStaticLink
-
- if (gDependenciesByDependent)
- gDependenciesByDependent->EachDependencyWithDependent(anObject, DeleteByDependent, &NullStaticLink);
- if (gDependenciesByNotifier)
- gDependenciesByNotifier->EachDependencyWithNotifier(anObject, DeleteByNotifier, &NullStaticLink);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void EachDependentOf(TObject* notifier,
- DoToObjectType DoToDependent,
- void* staticLink)
- {
- if (gDependenciesByNotifier)
- gDependenciesByNotifier->EachDependentDo(notifier, DoToDependent, staticLink);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void EachNotifierOf(TObject* dependent,
- DoToObjectType DoToNotifier,
- void* staticLink)
- {
- if (gDependenciesByDependent)
- gDependenciesByDependent->EachNotifierDo(dependent, DoToNotifier, staticLink);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
- pascal void MarkObject(TObject* anObject, Boolean state)
- {
- ArrayIndex index;
- DependencyPtr p;
-
- if (anObject)
- {
- if ((gDependenciesByDependent) && gDependenciesByDependent->FindDependent(anObject, index))
- {
- p = (DependencyPtr)gDependenciesByDependent->ComputeAddress(index);
- if ((state) != (p->dependencyLabel < 0))
- p->dependencyLabel = -(p->dependencyLabel);
- }
- else if ((gDependenciesByNotifier) && gDependenciesByNotifier->FindNotifier(anObject, index))
- {
- p = (DependencyPtr)gDependenciesByNotifier->ComputeAddress(index);
- if ((state) != (p->dependencyLabel < 0))
- p->dependencyLabel = -(p->dependencyLabel);
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
- pascal Boolean IsObjectMarked(TObject* anObject)
- {
- ArrayIndex index;
-
- if (anObject)
- {
- if ((gDependenciesByDependent) && gDependenciesByDependent->FindDependent(anObject, index))
- {
- return (((DependencyPtr)gDependenciesByDependent->ComputeAddress(index))->dependencyLabel < 0);
- }
- else if ((gDependenciesByNotifier) && gDependenciesByNotifier->FindNotifier(anObject, index))
- {
- return (((DependencyPtr)gDependenciesByNotifier->ComputeAddress(index))->dependencyLabel < 0);
- }
- else
- return FALSE;
- }
- else
- return FALSE;
- }
-
- //--------------------------------------------------------------------------------------------------
- // CDependencyComparer
- //--------------------------------------------------------------------------------------------------
-
- #pragma segment DepRes
-
- class CDependencyComparer
- {
- Dependency& fTargetDependency;
- TDependencies* fDependencies;
- public:
- // Constructor
- CDependencyComparer(Dependency& targetDependency,
- TDependencies* theDependencies) :
- fTargetDependency(targetDependency),
- fDependencies(theDependencies) {}
-
- pascal CompareResult CompareDependency(ArrayIndex index);
- };
-
- #pragma segment DepRes
-
- pascal CompareResult CDependencyComparer::CompareDependency(ArrayIndex index)
- {
- return fDependencies->CompareElements(&fTargetDependency, fDependencies->ComputeAddress(index));
- }
-
- //--------------------------------------------------------------------------------------------------
- // CObjectIterator
- //--------------------------------------------------------------------------------------------------
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- class CDependentIterator
- {
- DoToObjectType& fDoToObject;
- void*& fStaticLink;
- public:
- // Constructor
- CDependentIterator(DoToObjectType& DoToObject,
- void*& staticLink) :
- fDoToObject(DoToObject),
- fStaticLink(staticLink)
- {
- }
-
- pascal void DoToDependent(ArrayIndex /* index */,
- TObject* /* notifier */,
- TObject* dependent,
- DependencyLabels /* dependencyLabel */);
- pascal void DoToNotifier(ArrayIndex /* index */,
- TObject* /* notifier */,
- TObject* dependent,
- DependencyLabels /* dependencyLabel */);
-
- };
-
- #pragma segment DepRes
-
- pascal void CDependentIterator::DoToDependent(ArrayIndex /* index */,
- TObject* /* notifier */ ,
- TObject* dependent,
- DependencyLabels/* dependencyLabel */)
-
- {
- fDoToObject(dependent, fStaticLink);
- }
-
- #pragma segment DepRes
-
- pascal void CDependentIterator::DoToNotifier(ArrayIndex /* index */,
- TObject* notifier,
- TObject* /* dependent */,
- DependencyLabels/* dependencyLabel */)
-
- {
- fDoToObject(notifier, fStaticLink);
- }
-
- //--------------------------------------------------------------------------------------------------
- // TDependencies
- //--------------------------------------------------------------------------------------------------
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependencies::IDependencies(void)
- {
- this->IDynamicArray(1, sizeof(Dependency));
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependencies::AddDependency(TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel)
- {
- ArrayIndex index;
-
- if (!FindDependency(notifier, dependent, dependencyLabel, index))
- this->InsertDependencyBefore(index, notifier, dependent, dependencyLabel);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependencies::InsertDependencyBefore(ArrayIndex index,
- TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel)
- {
- Dependency newDependency(notifier,dependent,dependencyLabel);
-
- this->InsertElementsBefore(index, &newDependency, 1);
- }
-
-
- #pragma segment DepRes
-
- pascal Boolean TDependencies::FindDependency(TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel,
- ArrayIndex& index)
-
-
- {
- Dependency targetDependency(notifier,dependent,dependencyLabel);
- CDependencyComparer aDependencyComparer(targetDependency, this);
-
- return this->DoSearchElement((CompareIndexType) & CDependencyComparer::CompareDependency, &aDependencyComparer, index);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependencies::RemoveDependency(TObject* notifier,
- TObject* dependent,
- DependencyLabels dependencyLabel)
- {
- ArrayIndex index;
-
- if (this->FindDependency(notifier, dependent, dependencyLabel, index))
- this->DeleteElementsAt(index, 1);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MAFields
-
- pascal void TDependencies::Fields(TObject* obj) // override
- {
- obj->DoToField("TDependencies", (Ptr)NULL, bClass);
-
- inherited::Fields(obj);
- }
-
-
- #pragma segment MAFields
-
- pascal void TDependencies::DynamicFields(TObject* obj)// override
- {
- CArrayIterator iter(this);
- Str255 aString;
-
- obj->DoToField("Dynamic Fields", NULL, bTitle);
-
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- {
- Dependency& theDependency = *((DependencyPtr) this->ComputeAddress(i));
-
- NumToString(i, aString);
- aString = ".At[" + aString + "]";
- obj->DoToField(aString, &theDependency.notifier, bTitle);
- obj->DoToField("Notifier", &theDependency.notifier, bObject);
- obj->DoToField("Dependent", &theDependency.dependent, bObject);
- obj->DoToField("dependencyLabel", &theDependency.dependencyLabel, bInteger);
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- // TDependenciesByNotifier
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal CompareResult TDependenciesByNotifier::CompareElements(void* Element1,
- void* Element2)// override
-
- {
- Dependency & Dependency1 = *((DependencyPtr)Element1);
- Dependency & Dependency2 = *((DependencyPtr)Element2);
-
- if (Dependency1.notifier > Dependency2.notifier)
- return kItem1GreaterThanItem2;
- else if (Dependency1.notifier < Dependency2.notifier)
- return kItem1LessThanItem2;
- else
- {
- if ((Dependency1.dependent == NULL) || (Dependency2.dependent == NULL) || (Dependency1.dependent == Dependency2.dependent))
- return kItem1EqualItem2;
- else if (Dependency1.dependent < Dependency2.dependent)
- return kItem1LessThanItem2;
- else
- return kItem1GreaterThanItem2;
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal Boolean TDependenciesByNotifier::FindNotifier(TObject* notifier,
- ArrayIndex& index)
- {
- Dependency targetDependency(notifier,NULL,kNoLabel);
- CDependencyComparer aDependencyComparer(targetDependency, this);
-
- return this->DoSearchElement((CompareIndexType) & CDependencyComparer::CompareDependency, &aDependencyComparer, index);
- }
-
- #pragma segment DepRes
-
- pascal void TDependenciesByNotifier::EachDependencyWithNotifier(TObject* notifier,
- DoToDependencyType DoToDependency,
- void* staticLink)
-
-
- {
- ArrayIndex foundIndex;
-
- // Although the lists are ordered the search is a binary search and can return
- // a random entry from the set of matching entries. First back up the the _real_
- // first matching entry and then we will march forward applying the DoToDependency
-
- if (this->FindNotifier(notifier, foundIndex))
- {
- {// extra block to ensure iterators are destroyed in fifo order
- CArrayIterator iter(this, 1, foundIndex, kIterateBackward);
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- {
- if (((DependencyPtr)this->ComputeAddress(i))->notifier == notifier)
- foundIndex = i;
- else
- break;
- }
- }
-
- {// extra block to ensure iterators are destroyed in fifo order
- CArrayIterator iter(this, foundIndex, fSize, kIterateForward);
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- {
- Dependency & theDependency = *((DependencyPtr)this->ComputeAddress(i));
-
- if (theDependency.notifier == notifier)
- DoToDependency(i, theDependency.notifier, theDependency.dependent, theDependency.dependencyLabel, staticLink);
- else
- break;
- }
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependenciesByNotifier::EachDependentDo(TObject* notifier,
- DoToObjectType DoToDependent,
- void* staticLink)
-
-
- {
- CDependentIterator aDependentIterator(DoToDependent, staticLink);
-
- this->EachDependencyWithNotifier(notifier, (DoToDependencyType) &CDependentIterator::DoToDependent, &aDependentIterator);
- }
-
- //--------------------------------------------------------------------------------------------------
- // TDependenciesByDependent
- //--------------------------------------------------------------------------------------------------
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal CompareResult TDependenciesByDependent::CompareElements(void* Element1,
- void* Element2) // override
- {
- Dependency& Dependency1 = *((DependencyPtr)Element1);
- Dependency& Dependency2 = *((DependencyPtr)Element2);
-
- if (Dependency1.dependent > Dependency2.dependent)
- return kItem1GreaterThanItem2;
- else if (Dependency1.dependent < Dependency2.dependent)
- return kItem1LessThanItem2;
- else
- {
- if ((Dependency1.notifier == NULL) || (Dependency2.notifier == NULL) || (Dependency1.notifier == Dependency2.notifier))
- return kItem1EqualItem2;
- else if (Dependency1.notifier < Dependency2.notifier)
- return kItem1LessThanItem2;
- else
- return kItem1GreaterThanItem2;
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal Boolean TDependenciesByDependent::FindDependent(TObject* dependent,
- ArrayIndex& index)
- {
- Dependency targetDependency(NULL,dependent,kNoLabel);
- CDependencyComparer aDependencyComparer(targetDependency, this);
-
- return this->DoSearchElement((CompareIndexType) &CDependencyComparer::CompareDependency, &aDependencyComparer, index);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependenciesByDependent::EachNotifierDo(TObject* dependent,
- DoToObjectType DoToNotifier,
- void* staticLink)
-
-
- {
- CDependentIterator aDependentIterator(DoToNotifier, staticLink);
-
- this->EachDependencyWithDependent(dependent, (DoToDependencyType) &CDependentIterator::DoToNotifier, &aDependentIterator);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment DepRes
-
- pascal void TDependenciesByDependent::EachDependencyWithDependent(TObject* dependent,
- DoToDependencyType DoToDependency,
- void* staticLink)
- {
- ArrayIndex foundIndex;
-
- // Although the lists are ordered the search is a binary search and can return
- // a random entry from the set of matching entries. First back up the the _real_
- // first matching entry and then we will march forward applying the DoToDependency
-
- if (this->FindDependent(dependent, foundIndex))
- {
- {// extra block to ensure iterators are destroyed in fifo order
- CArrayIterator iter(this, 1, foundIndex, kIterateBackward);
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- {
- if (((DependencyPtr)this->ComputeAddress(i))->dependent == dependent)
- foundIndex = i;
- else
- break;
- }
- }
-
- {// extra block to ensure iterators are destroyed in fifo order
- CArrayIterator iter(this, foundIndex, fSize, kIterateForward);
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- {
- Dependency & theDependency = *((DependencyPtr)this->ComputeAddress(i));
-
- if (theDependency.dependent == dependent)
- DoToDependency(i, theDependency.notifier, theDependency.dependent, theDependency.dependencyLabel, staticLink);
- else
- break;
- }
- }
- }
- }
-
-
-